<script setup lang="ts">
import { ref, computed, nextTick } from 'vue';
const props: any = defineProps<{
    ujt: any;
    params: any;
}>();
const { $fn } = props.ujt;

const croppedImage = ref('');
const previewImage = ref(null);
const cutImage = ref(null);
const previewContainer = ref(null);

// 裁剪框参数
const cropParams = ref({
    x: 0,
    y: 0,
    width: 0,
    height: 0,
    maxWidth: 0,
    maxHeight: 0,
});

// 交互状态
const interaction = ref({
    type: null,
    startX: 0,
    startY: 0,
    originalX: 0,
    originalY: 0,
    originalWidth: 0,
    originalHeight: 0,
    direction: null,
});

// 计算裁剪框样式
const cropBoxStyle = computed(() => {
    return {
        transform: `translate(${cropParams.value.x}px, ${cropParams.value.y}px)`,
        width: `${cropParams.value.width}px`,
        height: `${cropParams.value.height}px`,
    };
});

const showCropBox = computed(
    () => cropParams.value.width > 0 && cropParams.value.height > 0
);

// 初始化裁剪框
const initCropBox = () => {
    const img = previewImage.value;
    const container = previewContainer.value;
    if (!img || !container) {
        console.error('Image or container element not found.');
        return;
    }
    const maxWidth = Math.min(container.clientWidth, img.naturalWidth);
    const maxHeight = Math.min(container.clientHeight, img.naturalHeight);

    const initWidth = Math.min(maxWidth * 0.8, img.naturalWidth);
    const initHeight = Math.min(maxHeight * 0.8, img.naturalHeight);

    cropParams.value = {
        x: (maxWidth - initWidth) / 2,
        y: (maxHeight - initHeight) / 2,
        width: initWidth,
        height: initHeight,
        maxWidth,
        maxHeight,
    };
    console.log('Initial crop params:', cropParams.value);
};

// 开始交互
const startInteraction = (type, direction = null) => {
    console.log('Interaction started:', type, direction);
    const event = window.event || event;
    const touch = event.touches ? event.touches[0] : event;
    interaction.value = {
        type,
        startX: touch.clientX,
        startY: touch.clientY,
        originalX: cropParams.value.x,
        originalY: cropParams.value.y,
        originalWidth: cropParams.value.width,
        originalHeight: cropParams.value.height,
        direction,
    };

    const moveHandler = (e) => {
        requestAnimationFrame(() => {
            if (type === 'move') {
                handleMove(e);
            } else {
                handleResize(e);
            }
        });
    };

    window.addEventListener('mousemove', moveHandler);
    window.addEventListener('touchmove', moveHandler);
    window.addEventListener('mouseup', stopInteraction);
    window.addEventListener('touchend', stopInteraction);
};

// 处理移动
const handleMove = (e) => {
    const event = window.event || e;
    const touch = event.touches ? event.touches[0] : event;
    if (interaction.value.type !== 'move') return;

    const dx = touch.clientX - interaction.value.startX;
    const dy = touch.clientY - interaction.value.startY;

    const newX = Math.max(
        0,
        Math.min(
            interaction.value.originalX + dx,
            cropParams.value.maxWidth - cropParams.value.width
        )
    );

    const newY = Math.max(
        0,
        Math.min(
            interaction.value.originalY + dy,
            cropParams.value.maxHeight - cropParams.value.height
        )
    );

    Object.assign(cropParams.value, { x: newX, y: newY });
};

// 处理调整大小
const handleResize = (e) => {
    const event = window.event || e;
    const touch = event.touches ? event.touches[0] : event;
    if (interaction.value.type !== 'resize') return;

    const dx = touch.clientX - interaction.value.startX;
    const dy = touch.clientY - interaction.value.startY;
    const direction = interaction.value.direction;

    let newWidth = interaction.value.originalWidth;
    let newHeight = interaction.value.originalHeight;
    let newX = interaction.value.originalX;
    let newY = interaction.value.originalY;

    switch (direction) {
        case 'tr':
            newWidth = Math.max(
                100,
                Math.min(
                    interaction.value.originalWidth + dx,
                    cropParams.value.maxWidth - newX
                )
            );
            newHeight = Math.max(100, interaction.value.originalHeight - dy);
            newY = Math.max(0, interaction.value.originalY + dy);
            break;
        case 'tl':
            newWidth = Math.max(100, interaction.value.originalWidth - dx);
            newHeight = Math.max(100, interaction.value.originalHeight - dy);
            newX = Math.max(0, interaction.value.originalX + dx);
            newY = Math.max(0, interaction.value.originalY + dy);
            break;
        case 'br':
            newWidth = Math.max(100, interaction.value.originalWidth + dx);
            newHeight = Math.max(100, interaction.value.originalHeight + dy);
            break;
        case 'bl':
            newWidth = Math.max(100, interaction.value.originalWidth - dx);
            newHeight = Math.max(100, interaction.value.originalHeight + dy);
            newX = Math.max(0, interaction.value.originalX + dx);
            break;
    }

    // 确保裁剪框不超出图片边界
    newWidth = Math.min(newWidth, cropParams.value.maxWidth - newX);
    newHeight = Math.min(newHeight, cropParams.value.maxHeight - newY);

    Object.assign(cropParams.value, {
        x: newX,
        y: newY,
        width: newWidth,
        height: newHeight,
    });
    console.log('Resized crop params:', cropParams.value);
};

// 停止交互
const stopInteraction = () => {
    interaction.value.type = null;
    window.removeEventListener('mousemove', handleMove);
    window.removeEventListener('touchmove', handleMove);
    window.removeEventListener('mousemove', handleResize);
    window.removeEventListener('touchmove', handleResize);
    window.removeEventListener('mouseup', stopInteraction);
    window.removeEventListener('touchend', stopInteraction);
};

// 执行裁剪
const cropImage = () => {
    const img: any = previewImage.value;
    const scaleX = img.naturalWidth / img.width;
    const scaleY = img.naturalHeight / img.height;

    const canvasWidth = Math.min(
        cropParams.value.width * scaleX,
        img.naturalWidth
    );
    const canvasHeight = Math.min(
        cropParams.value.height * scaleY,
        img.naturalHeight
    );

    const canvas = document.createElement('canvas');
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    const ctx = canvas.getContext('2d');
    ctx.drawImage(
        img,
        cropParams.value.x * scaleX,
        cropParams.value.y * scaleY,
        canvasWidth,
        canvasHeight,
        0,
        0,
        canvasWidth,
        canvasHeight
    );

    croppedImage.value = canvas.toDataURL('image/png', 0.9);

    if (props.params.asaidata?.rule?.[props.params?.formkey]?.data) {
        nextTick(() => {
            let maxSize = props.params.asaidata.rule[props.params.formkey].data;
            let cutSize: any = {};
            if (maxSize.width < canvasWidth || maxSize.height < canvasHeight) {
                if (
                    maxSize.height / canvasHeight >
                    maxSize.width / canvasWidth
                ) {
                    cutSize.width = maxSize.width;
                    cutSize.height =
                        (canvasHeight * maxSize.width) / canvasWidth;
                } else {
                    cutSize.width =
                        (canvasWidth * maxSize.height) / canvasHeight;
                    cutSize.height = maxSize.height;
                }
                const cutmg: any = cutImage.value;

                const canvas1 = document.createElement('canvas');
                canvas1.width = cutSize.width;
                canvas1.height = cutSize.height;

                const ctx1 = canvas1.getContext('2d');
                ctx1.drawImage(cutmg, 0, 0, cutSize.width, cutSize.height);
                croppedImage.value = canvas1.toDataURL('image/png', 0.9);
            }
        });
    }
};

// 下载图片
const downloadImage = () => {
    const link = document.createElement('a');
    link.download = 'cropped-image.png';
    link.href = croppedImage.value;
    link.click();
};
// 确认图片
const uploadImage = () => {
    props.params.fn(croppedImage.value);
};
</script>

<template>
    <div class="as-img-area">
        <div v-if="croppedImage" class="as-img-preview">
            <img ref="cutImage" :src="croppedImage" />
        </div>
        <div v-else class="as-img-cut" ref="previewContainer">
            <img
                ref="previewImage"
                :src="props.params.base64Data"
                @load="initCropBox"
            />
            <div
                v-show="showCropBox"
                class="as-img-crop-box"
                :style="cropBoxStyle"
                @mousedown.prevent="startInteraction('move')"
                @touchstart.prevent="startInteraction('move')"
            >
                <div
                    class="as-img-crop-handle top-left"
                    @mousedown.stop="startInteraction('resize', 'tl')"
                    @touchstart.stop="startInteraction('resize', 'tl')"
                ></div>
                <div
                    class="as-img-crop-handle top-right"
                    @mousedown.stop="startInteraction('resize', 'tr')"
                    @touchstart.stop="startInteraction('resize', 'tr')"
                ></div>
                <div
                    class="as-img-crop-handle bottom-left"
                    @mousedown.stop="startInteraction('resize', 'bl')"
                    @touchstart.stop="startInteraction('resize', 'bl')"
                ></div>
                <div
                    class="as-img-crop-handle bottom-right"
                    @mousedown.stop="startInteraction('resize', 'br')"
                    @touchstart.stop="startInteraction('resize', 'br')"
                ></div>
            </div>
        </div>
        <div class="as-img-btns">
            <template v-if="croppedImage">
                <button @pointerdown="downloadImage">下载图片</button>
                <button @pointerdown="uploadImage">确认上传</button>
            </template>
            <button v-else @pointerdown="cropImage">确认裁剪</button>
        </div>
    </div>
</template>

<style scoped lang="scss">
.as-img-area {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.as-img-preview {
    flex-grow: 1;
    display: flex;
    justify-content: center;
    align-items: center;

    img {
        max-width: 100%;
        max-height: 100%;
    }
}

.as-img-cut {
    flex-grow: 1;
    position: relative;
    overflow: hidden;

    img {
        display: block;
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
    }
}

.as-img-crop-box {
    position: absolute;
    top: 0;
    left: 0;
    border: 2px solid #fff;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);
    cursor: move;
}

.as-img-crop-handle {
    position: absolute;
    width: 12px;
    height: 12px;
    background: #fff;
    border: 2px solid #409eff;
    border-radius: 50%;
}

.top-left {
    left: -6px;
    top: -6px;
    cursor: nwse-resize;
}

.top-right {
    right: -6px;
    top: -6px;
    cursor: nesw-resize;
}

.bottom-left {
    left: -6px;
    bottom: -6px;
    cursor: nesw-resize;
}

.bottom-right {
    right: -6px;
    bottom: -6px;
    cursor: nwse-resize;
}

.as-img-btns {
    height: auto;
    padding: 5px 12px;
    display: flex;
    justify-content: center;

    button {
        height: 38px;
        padding: 0 20px;
        margin: 0 8px;
        background-color: var(--cm6);
        color: var(--cm0);
        border-radius: 4px;
        cursor: pointer;
    }
}
</style>
